const fs = require('fs')
const { v4: uuidv4 } = require('uuid')
const uniq = require('lodash/uniq')
const replace = require('lodash/replace')

const capital = key => {
  const noun = {
    stage: 'Stage',
    line: 'Line',
    layer: 'Layer',
    point: 'Point',
    block: 'Block',
    arc: 'Arc',
    ellipse: 'Ellipse',
    text: 'Text',
    polyline: 'Polyline',
    wall: 'Wall',
    opening: 'Opening',
    entity: 'Entity',
    mainwall: 'MainWall',
    solid: 'Solid',
    drywall: 'DryWall',
    door: 'Door',
    window: 'Window',
    circle: 'Circle',
    beam: 'Beam',
    column: 'Column',
    room: 'Room',
    apartment: 'Apartment', //template
    scanstation: 'Scanstation', //scanstation
    building: 'Building',
    ceiling: 'Ceiling',
    floor: 'Floor',
    concrete: 'Concrete',
    masonry: 'Masonry',
    plaster: 'Plaster',
    separator: 'Separator'
  }
  if (noun[key]) {
    return noun[key]
  } else {
    return key
  }
}

const addCurrentTimeToUGM = ugm => {
  if (ugm.current_time) return ugm
  if (!ugm.data.cols.timestamp || !ugm.data.cols.timestamp.length) {
    const timestamp = { id: uuidv4(), timestamp: Date.now().toString(), definition: 'timestamp' }
    ugm.data.cols.timestamp = [timestamp]
    ugm.data.docs[timestamp.id] = timestamp
    ugm.current_time = timestamp.timestamp
  } else {
    ugm.current_time = ugm.timestamp[0].timestamp
  }
  return ugm
}

const cloneUGM = oldUGM => {
  if (oldUGM.data && oldUGM.bim) {
    const rendermaterials = oldUGM.elements.nodes.filter(i => i.definition === 'rendermaterial')
    const rendermaterialIds = rendermaterials.map(o => o.id)
    oldUGM.elements = { nodes: [...rendermaterials] }
    oldUGM.data.cols = {}
    oldUGM.bim.cols = {}
    const allId = uniq([...Object.keys(oldUGM.data.docs), ...Object.keys(oldUGM.bim.docs), ...rendermaterialIds])
    let newUGMStr = JSON.stringify(oldUGM)
    allId.forEach(id => {
      newUGMStr = replace(newUGMStr, new RegExp(id, 'g'), uuidv4())
    })
    const newUGM = JSON.parse(newUGMStr)
    const nodes = Object.values(newUGM.data.docs).map(node => {
      return { ...node, definition: capital(node.definition) }
    })
    newUGM.elements = { nodes: [...newUGM.elements.nodes, ...nodes] }
    newUGM.data.cols = {}
    newUGM.bim.cols = {}
    for (const key in newUGM.data.docs) {
      const node = newUGM.data.docs[key]
      const definition = node.definition
      if (definition) {
        if (!newUGM.data.cols[definition]) newUGM.data.cols[definition] = []
        newUGM.data.cols[definition].push(node)
      }
    }
    for (const key in newUGM.bim.docs) {
      const node = newUGM.bim.docs[key]
      const definition = node.definition
      if (definition) {
        if (!newUGM.bim.cols[definition]) newUGM.bim.cols[definition] = []
        newUGM.bim.cols[definition].push(node)
      }
    }
    newUGM.data.docs = {}
    newUGM.bim.docs = {}
    for (const key in newUGM.data.cols) {
      newUGM.data.cols[key].forEach(doc => {
        newUGM.data.docs[doc.id] = doc
      })
    }
    for (const key in newUGM.bim.cols) {
      newUGM.bim.cols[key].forEach(doc => {
        newUGM.bim.docs[doc.id] = doc
      })
    }
    return newUGM
  } else {
    const nodes = oldUGM.elements.nodes
    const allId = uniq(nodes.map(i => i.id))
    let newUGMStr = JSON.stringify(oldUGM)
    allId.forEach(id => {
      newUGMStr = replace(newUGMStr, id, uuidv4())
    })
    return JSON.parse(newUGMStr)
  }
}

const args = process.argv.splice(2)
const path = args[0]
const oldUGM = JSON.parse(fs.readFileSync(path, 'utf-8'))
const newUGM = addCurrentTimeToUGM(cloneUGM(oldUGM))
fs.writeFileSync(path, JSON.stringify(newUGM))
